# -*- coding: utf-8 -*-
import uuid
import cPickle
import logging
from model import WebSessionStore, session as dbsession


class WebSession(object):
    def __init__(self, session_id=None, store='', args={}):
        self.store = Session_Store_DBClass()
        self.data = self.store._DATA
        self.time = 86400
        if session_id:
            self.session_id = session_id
        else:
            self.session_id = self._generate_session_id()

    def _generate_session_id(cls):
        return str(uuid.uuid4())

    @property
    def id(self):
        return self.session_id

    def set(self, key, value):
        self.store.set(self.session_id, key, value, self.time)

    def get(self, key):
        logging.debug('[WebSession.get]:' + self.session_id + key)
        return self.store.get(self.session_id, key)

    def delete(self, key):
        self.store.delete(self.session_id, key)

    def clear(self):
        self.store.clear(self.session_id)

    def __getitem__(self, key):
        return self.get(key)

    def __setitem__(self, key, value):
        return self.set(key, value)

    def __delitem__(self, key):
        return self.delete(key)

    def __len__(self):
        return len(self.data.keys())

    def __str__(self):
        return str(self.data)

    def keys(self):
        return self.data.keys()


class Session_Store_StaticClass:
    _DATA = {}

    def get_session(self, session_id):
        if session_id in Session_Store_StaticClass._DATA:
            return Session_Store_StaticClass._DATA[session_id]
        return {}

    def set(self, session_id,  key, value, time=0):
        session = self.get_session(session_id)
        session[key] = value
        Session_Store_StaticClass._DATA[session_id] = session

    def get(self, session_id, key):
        logging.debug('[session get]:' + session_id + key)
        session = self.get_session(session_id)
        if key in session:
            return session[key]
        return {}

    def delete(self, session_id, key):
        session = self.get_session(session_id)
        if key in session:
            del session[key]
            Session_Store_StaticClass._DATA[session_id] = session

    def clear(self, session_id):
        if session_id in Session_Store_StaticClass._DATA:
            del Session_Store_StaticClass._DATA[session_id]


class Session_Store_DBClass:
    def __init__(self, *arg, **kw):
        class Data:
            def keys(self):
                return dbsession.query(WebSessionStore.id).all()

            def __str__(self):
                return '<Session_Store_DBClass>'
        self._DATA = Data()

    def get_session(self, session_id):
        s = dbsession.query(WebSessionStore).filter_by(id=session_id).scalar()
        if s:
            return cPickle.loads(s.value)
        return {}

    def set(self, session_id, key, value, time=0):
        session = self.get_session(session_id)
        session[key] = value
        s = dbsession.query(WebSessionStore).get(session_id)
        if not s:
            s = WebSessionStore(id=session_id)
            dbsession.add(s)
        s.value = cPickle.dumps(session)
        logging.debug('[Session_Store_DBClass set]: %s' % session)
        dbsession.flush()

    def get(self, session_id, key):
        session = self.get_session(session_id)
        if key in session:
            return session[key]
        return None

    def delete(self, session_id, key):
        session = self.get_session(session_id)
        if key in session:
            del session[key]
            s = dbsession.query(WebSessionStore)\
                .filter_by(id=session_id).scalar()
            s.value = cPickle.dumps(session)
            dbsession.add(s)
            dbsession.flush()

    def clear(self, session_id):
        s = dbsession.query(WebSessionStore).filter_by(id=session_id).scalar()
        if s:
            dbsession.delete(s)
            dbsession.flush()
